package com.dubbo.server.service;


import com.dubbo.server.config.AliyunSMSConfig;
import com.dubbo.server.vo.ErrorResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;

/**
 * 如果是我 肯定会写一个发送短信的工具类
 * public static String sendSms(String mobile,String code,String templateCode){调用阿里云发送短信}
 *
 * @Service 是把当前的Bean注入到Spring容器中
 * 在其他的类中要想发短信  就必须保证这个类是在Spring容器中的类
 * <p>
 * 如果我们在多个模块中都要发短信 你咋弄
 * <p>
 * 我们啥时候会去把一些值抽取到配置文件 ??
 * 就是这个值有可能会变化 而且这个值的变化 不会影响到业务代码
 */

/* 短信发送的服务类 */
@Service
@Slf4j
public class SmsService {


    /*
     * 工具类的功能尽量的单一 尽量的和业务拆分开
     * 工具类是在哪里使用的啊  ?
     * 肯定是在Service中使用 然后在Service中获取配置文件中的值然后再传递给工具类
     * 推荐: 在工具类中使用类加载器去读取文件
     * 通用的工具类:  发送验证码   工具类中生成 还是 传递给工具类
     * Boolean  如果我们的验证码是从Service中生成传递给工具类的  那么就只需要返回一个是否发送成功的标识就可以了
     * String   如果我们的验证码是从工具类中生成 那么发送成功之后要返回给Service   (推荐的写法  传递一个长度)
     * 形参:   手机号码   模板编号
     * */
    @Autowired
    private AliyunSMSConfig aliyunSMSConfig;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 发送短信验证码
     *
     * 返回值  Boolean
     * String mobile  ,  String templateCode , String code
     *
     * 发送短信验证码  + 生成验证码
     * 返回值  String
     * String mobile  ,  String templateCode , int len
     * 长度不一样  4  6
     *
     * 生成验证码  单独的写一个工具类
     * 数字的  指定长度
     * 字母的  指定长度
     * 数字+字母 指定长度
     *
     * @param mobile
     * @return
     */


    /**
     * 发送短信验证码
     * 实现：发送完成短信验证码后，需要将验证码保存到redis中
     *
     * @param phone
     * @return
     */
    public ErrorResult sendCheckCode(String phone) {

        //随机生成验证码
        String code = RandomUtils.nextInt(100000, 999999) + "";
        System.out.println("验证码.........:" + code);
        //唯一标识(Redis  缓存 Key  成百上千的Key(这个Key的定义最好是搞一个常量类去记录))
        String redisKey = "sso_login_sendCheckCode" + phone;
        //校验 正则
        boolean matches = phone.matches("^(1[3-9][0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$");
        if (!matches) {
            return ErrorResult.builder().errCode("100003").errMessage("手机号码不合法").build();
        }
        //判断该手机号发送的验证码是否还未失效
        if (this.redisTemplate.hasKey(redisKey)) {
            String msg = "上一次发送的验证码还未失效！";
            return ErrorResult.builder().errCode("000001").errMessage(msg).build();
        }
        // 去调用阿里云发送短信
        // String code = "123456";
        //SedSms.sendMsg(phone,"你的验证码",code);
        //String code = this.sendSms(phone);
        /*如果你是封装了一个发送短信的工具类  在这边生成一个随机的验证码 然后传递到工具类里面   你就可以判断是否发送成功 然后再把这个验证码存储到redis中  */
        if (StringUtils.isEmpty(code)) {
            String msg = "发送短信验证码失败！";
            return ErrorResult.builder().errCode("000000").errMessage(msg).build();
        }
        // 同一个手机号码 5分钟内只能发送一次
        //redisTemplate.opsForValue().set(phone, code, 5, TimeUnit.MINUTES);
        this.redisTemplate.opsForValue().set(redisKey, code, Duration.ofMinutes(5));

        return null;
    }


}
